package net.sh.dpinfrastructure.support.openapi;

import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.format.datetime.joda.DateTimeFormatterFactory;

/**
 * api请求上下文
 * @author Lancer
 * @date 2015年8月22日下午6:55:34
 *
 */
public class DPApiContext {
    
    /***************系统参数******************/
    
    /**
     * appkey 参数名
     */
    public static final String N_APP_KEY = "_ak";
    
    /**
     * 请求签名，该参数值每次请求都应该唯一
     */
    public static final String N_REQUEST_SIGNATURE = "_s";
    
    /**
     * 请求时间戳
     */
    public static final String N_TIMESTAMP = "_ts";
    
    /**
     * 系统参数，appkey，访问戳，时间戳
     */
    protected static final String[] SYSTEM_PARAMS = new String[] {
        N_APP_KEY, N_REQUEST_SIGNATURE, N_TIMESTAMP
    };
    
    /***************默认参数，即预定义了部分api共享的参数，如分页排序等等字段******************/
    
    /**
     * 请求页（当前页）
     */
    public static final String N_PAGE = "page";
    
    /**
     * 每页显示条数
     */
    public static final String N_ROWS = "rows";
    
    /**
     * 排序字段，可以多个，使用';'相隔
     */
    public static final String N_ORDER_FIELDS = "order_fields";
    
    /**
     * 排序类型，可以多个，使用';'相隔. 个数应该同{@link #N_ORDER_FIELDS}相同，如果个数不一致则报错
     */
    public static final String N_ORDER_TYPES = "order_types";
    
    /**
     * 是否在返回记录集的同时，返回符合查询条件的记录总数
     */
    public static final String N_COUNT = "with_count";
    
    /**
     * 是否只返回符合查询条件的记录总数
     */
    public static final String N_ONLY_COUNT = "only_count";
    
    /**
     * 是否使用jsonp方式返回
     */
    public static final String N_JSONP = "jsonp";
    
    /**
     * 返回字段，使用';'分隔
     */
    public static final String N_FIELDS = "fields";
    
    protected static final String[] DEFAULT_API_PARAMS = new String[] {
        N_PAGE, N_ROWS, N_ORDER_FIELDS, N_ORDER_TYPES, N_COUNT, N_ONLY_COUNT, N_JSONP, N_FIELDS
    };
    
    /**
     * 请求的api
     */
    private DPApi api;
    
    /**
     * 请求该app
     */
    private DPApp app;
    
    /**
     * 上传的文件
     */
    private List<File> files;

    /**
     * 是否完整校验，完整校验：...，非完整校验...
     */
    private boolean fullVerify;

    /**
     * api 参数
     */
    private Map<String, String> apiParams;
    
    /**
     * 访问超时时间
     */
    private long requestTimeout;
    

    /**
     * 请求的资源
     */
    private String resource;


    /**
     * 系统参数<br>
     * @see 
     */
    private Map<String, String> sysParams;

    public DPApiContext(Map<String, String> apiParams) {
        this.apiParams = apiParams;
    }
    
    public DPApiContext(Map<String, String> apiParams, Map<String, String> sysParams) {
        this.apiParams = apiParams;
        this.sysParams = sysParams;
    }
    
    public DPApi getApi() {
        return api;
    }
    
    public DPApp getApp() {
        return app;
    }

    /**
     * 
     * 检查指定参数是否存在
     * 
     * @param paramName
     * @return
     *
     * @author shaohui
     * @date 2017年2月11日下午3:05:32
     * @since JDK 1.8
     */
    public boolean existParam(String paramName) {
        return StringUtils.isNotEmpty(apiParams.get(paramName)) || StringUtils.isNotEmpty(sysParams.get(paramName));
    }
    
    /**
     * 
     * 检查指定系统参数是否存在<br>
     * 
     * @param paramName
     * @return
     *
     * @author shaohui
     * @date 2017年2月11日下午3:05:32
     * @since JDK 1.8
     */
    public boolean existSysParam(String paramName) {
        return StringUtils.isNotEmpty(sysParams.get(paramName));
    }
    
    /**
     * 
     * 检查指定api参数是否存在<br/> 
     * 
     * @param paramName
     * @return
     *
     * @author shaohui
     * @date 2017年2月11日下午3:14:47
     * @since JDK 1.8
     */
    public boolean existApiParam(String paramName) {
        return StringUtils.isNotEmpty(apiParams.get(paramName));
    }
    
    /**
     * 
     * 获取appkey
     *
     * @return
     * 
     * @author shaohui
     * @date 2015年9月10日 下午9:47:22
     */
    public String getAppkey() {
        return sysParams.get("appkey");
    }

    
    /**
     * 
     * 获取时间参数（按照默认格式）<br/>
     * Lancer
     * 2015年8月22日下午7:03:30
     * @param paramName
     * @return
     *
     */
    public Date getDateParam(String paramName) {
        return getDateParam(paramName, "yyyy-MM-dd");
    }

    
    /**
     * 
     * 获取自定义格式的日期参数
     * Lancer
     * 2015年8月23日下午1:47:59
     * @param paramName
     * @param formatter
     * @return
     *
     */
    public Date getDateParam(String paramName, String pattern) {
        String paramValue = apiParams.get(paramName);
        if (StringUtils.isBlank(paramValue)) {
            return null;
        }
        DateTimeFormatter formatter = new DateTimeFormatterFactory(pattern).createDateTimeFormatter();
        return DateTime.parse(paramValue, formatter).toDate();
    }

    
    /**
     * 获取浮点型参数
     * Lancer
     * 2015年8月23日下午2:51:06
     * @param paramName
     * @return
     *
     */
    public Double getDoubleParam(String paramName) {
        try {
            return Double.parseDouble(apiParams.get(paramName));
        } catch (NumberFormatException e) {
            return null;
        }
    }

    
    /**
     * 
     * 获取浮点型参数
     * Lancer
     * 2015年8月29日上午11:12:24
     * @param paramName
     * @return
     *
     */
    public Double getDoubleParam(String paramName, Double defaultValue) {
        Double paramValue = defaultValue;
        try {
            paramValue = Double.parseDouble(apiParams.get(paramName));
        } catch (NumberFormatException e) {}
        return paramValue;
    }

    public List<File> getFiles() {
        return files;
    }
    
    /**
     * 获取浮点型参数
     * Lancer
     * 2015年8月23日下午2:51:06
     * @param paramName
     * @return
     *
     */
    public Float getFloatParam(String paramName) {
        try {
            return Float.parseFloat(apiParams.get(paramName));
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    /**
     * 
     * 获取浮点型参数
     * Lancer
     * 2015年8月29日上午11:14:38
     * @param paramName
     * @param defaultValue 默认值
     * @return
     *
     */
    public Float getFloatParam(String paramName, Float defaultValue) {
        Float paramValue = defaultValue;
        try {
            paramValue = Float.parseFloat(apiParams.get(paramName));
        } catch (NumberFormatException e) {}
        return paramValue;
    }
    
    /**
     * 
     * 获取整型参数
     * Lancer
     * 2015年8月23日下午2:50:36
     * @param paramName
     * @return
     *
     */
    public Integer getIntegerParam(String paramName) {
        try {
            return Integer.parseInt(apiParams.get(paramName));
        } catch (NumberFormatException e) {
            if ("order_type".equals(paramName)) {
                return 1;
            } else if ("page".equals(paramName)) {
                return 1;
            } else if ("rows".equals(paramName)) {
                return 20;
            } else {
                return null;
            }
        }
    }
    
    /**
     * 
     * 获取整型参数
     * Lancer
     * 2015年8月23日下午2:50:36
     * @param paramName
     * @param defaultValue 默认值
     * @return
     *
     */
    public Integer getIntegerParam(String paramName, Integer defaultValue) {
        Integer paramValue = defaultValue;
        try {
            paramValue = Integer.parseInt(apiParams.get(paramName));
        } catch (NumberFormatException e) {}
        return paramValue;
    }
    
    /**
     * 
     * Lancer
     * 2015年8月29日上午11:37:45
     * @return
     *
     */
    public List<String> getListParam(String paramName) {
        return getListParam(paramName, ";");
    }
    
    /**
     * 
     * Lancer
     * 2015年8月29日上午11:40:42
     * @param paramName
     * @param pattern
     * @return
     *
     */
    public List<String> getListParam(String paramName, String pattern) {
        String paramValue = apiParams.get(paramName);
        if (StringUtils.isBlank(paramValue)) {
            return null;
        }
        return Arrays.asList(paramValue.split(pattern));
    }
    
    /**
     * 
     * 获取长整型参数
     * Lancer
     * 2015年8月23日下午2:50:51
     * @param paramName
     * @return
     *
     */
    public Long getLongParam(String paramName) {
        try {
            return Long.parseLong(apiParams.get(paramName));
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    /**
     * 
     * 获取长整型参数
     * Lancer
     * 2015年8月29日上午11:10:52
     * @param paramName
     * @param defaultValue 默认值
     * @return
     *
     */
    public Long getLongParam(String paramName, Long defaultValue) {
        Long paramValue = defaultValue;
        try {
            paramValue = Long.parseLong(apiParams.get(paramName));
        } catch (NumberFormatException e) {}
        return paramValue;
    }
    
    /**
     * 
     * getStringParam(String paramName)的简写
     * Lancer
     * 2015年8月29日上午11:16:18
     * @param paramName
     * @return
     * @see 
     */
    public String getParam(String paramName) {
        return apiParams.get(paramName);
    }
    
    /**
     * 
     * getStringParam(String paramName, String defaultValue)的简写
     * Lancer
     * 2015年8月29日上午11:18:05
     * @param paramName
     * @param defaultValue
     * @return
     *
     */
    public String getParam(String paramName, String defaultValue) {
        return getStringParam(paramName, defaultValue);
    }
    
    /**
     * 
     * 获取参数键值对
     * Lancer
     * 2015年8月23日下午2:52:01
     * @return
     *
     */
    public Map<String, String> getApiParams() {
        return apiParams;
    }
    
    public long getRequestTimeout() {
        return requestTimeout;
    }
    
    public String getResource() {
        return resource;
    }
    
    /**
     * 
     * 获取字符串参数
     * Lancer
     * 2015年8月22日下午6:58:11
     * @param paramName
     * @return
     *
     */
    public String getStringParam(String paramName) {
        return apiParams.get(paramName);
    }
    
    /**
     * 
     * 获取字符串参数
     * Lancer
     * 2015年8月29日上午11:07:07
     * @param paramName
     * @param defaultValue 默认值
     * @return
     *
     */
    public String getStringParam(String paramName, String defaultValue) {
        String paramValue = apiParams.get(paramName);
        if (StringUtils.isBlank(paramValue)) {
            return defaultValue;
        }
        return paramValue;
    }
    
    /**
     * 
     * 获取系统参数
     *
     * @return
     * 
     * @author shaohui
     * @date 2015年9月10日 下午9:44:18
     */
    public Map<String, String> getSysParams() {
        return sysParams;
    }

    /**
     * 
     * 获取时间戳
     *
     * @return
     * 
     * @author shaohui
     * @date 2015年9月10日 下午9:46:50
     */
    public Long getTimestamp() {
        String time = sysParams.get("timestamp");
        if (StringUtils.isNotBlank(time)) {
            return Long.parseLong(time);
        }
        return null;
    }
    
    public boolean isFullVerify() {
        return fullVerify;
    }
    
    public void setApi(DPApi api) {
        this.api = api;
    }

    public void setApp(DPApp app) {
        this.app = app;
    }
    
    public void setFiles(List<File> files) {
        this.files = files;
    }
    
    public void setFullVerify(boolean fullVerify) {
        this.fullVerify = fullVerify;
    }
    
    public void setApiParams(Map<String, String> params) {
        this.apiParams = params;
    }
    
    public void setRequestTimeout(long requestTimeout) {
        this.requestTimeout = requestTimeout;
    }
    
    public void setResource(String resource) {
        this.resource = resource;
    }
    
    public void setSysParams(Map<String, String> sysParams) {
        this.sysParams = sysParams;
    }
}
